package cn.jarlen.jwt.tools.crypt.device.soft;

import java.io.ByteArrayInputStream;
import java.security.cert.CRL;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

import cn.jarlen.jwt.tools.crypt.base.CryptoAppKitProperties;
import cn.jarlen.jwt.tools.crypt.exception.CryptOperatorException;
import cn.jarlen.jwt.tools.crypt.operator.CertOperator;

public class SoftCertOperator implements CertOperator {
    private static final int CERT_VALIDITY_TYPE_CRL = 1;
    private static final int CERT_VALIDITY_TYPE_OCSP = 2;
    CryptoAppKitProperties.CertInfo certInfo = CryptoAppKitProperties.getInstance().getCertInfo();
    private static final SoftCertOperator softCryptOperator = new SoftCertOperator();

    public SoftCertOperator() {
    }

    public static SoftCertOperator getInstance() {
        return softCryptOperator;
    }

    public boolean certVerify(String cert) {
        SoftOperatorUtil.checkCertChain(cert, this.certInfo.getRootCertPath(), this.certInfo.getCertChainFilePath());
        if (1 == this.certInfo.getCertValidityType()) {
            this.checkCertByLdap(cert, this.certInfo.getCrlDn(), this.certInfo.getLdapIp(), this.certInfo.getLdapPort(), this.certInfo.getCrlFileCachePath());
        } else if (2 == this.certInfo.getCertValidityType()) {
        }
        return true;
    }

    private void checkCertByLdap(String cert, String crlDn, String ldapIp, String ldapPort, String crlFilePath) {
        X509Certificate x509Certificate = SoftOperatorUtil.getCertFromStr(cert);
        String certSerialNumber = x509Certificate.getSerialNumber().toString(16).toLowerCase();
        List<X509CRL> crlList = SoftOperatorUtil.getCrlList(crlFilePath);
        if (null == crlList) {
            crlList = this.getCrlList(crlDn, ldapIp, ldapPort, crlFilePath);
        }

        Iterator var9 = crlList.iterator();
        while (true) {
            Set revokedCertificates;
            do {
                if (!var9.hasNext()) {
                    return;
                }
                X509CRL crl = (X509CRL) var9.next();
                revokedCertificates = crl.getRevokedCertificates();
            } while (null == revokedCertificates);
            Iterator var12 = revokedCertificates.iterator();
            while (var12.hasNext()) {
                X509CRLEntry revokedCertificate = (X509CRLEntry) var12.next();
                if (certSerialNumber.equals(revokedCertificate.getSerialNumber().toString(16).toLowerCase())) {
                    throw new CryptOperatorException("该证书已撤销不可用");
                }
            }
        }
    }

    private List<X509CRL> getCrlList(String crlDn, String ldapIp, String ldapPort, String crlFilePath) {
        Hashtable<String, String> env = new Hashtable();
        env.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
        env.put("java.naming.provider.url", "ldap://" + ldapIp + ":" + ldapPort + "/");
        DirContext ctx = null;
        ArrayList crlList = new ArrayList();
        ArrayList var26;
        try {
            ctx = new InitialDirContext(env);
            String[] crlDnArry = crlDn.split(":");
            String[] var9 = crlDnArry;
            int var10 = crlDnArry.length;
            for (int var11 = 0; var11 < var10; ++var11) {
                String crlD = var9[var11];
                if (null != crlD && crlD.length() > 0) {
                    byte[] bsCrl = SoftOperatorUtil.lookupCrl(ctx, crlDn, this.certInfo.getCrlAttrName());
                    (new Thread(() -> {
                        SoftOperatorUtil.saveCrlFile(bsCrl, crlFilePath);
                    })).start();
                    ByteArrayInputStream bais = new ByteArrayInputStream(bsCrl);
                    CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
                    CRL crl = cf.generateCRL(bais);
                    if (null != crl) {
                        crlList.add((X509CRL) crl);
                    }
                }
            }
            var26 = crlList;
        } catch (Exception var24) {
            throw new CryptOperatorException("获取CRL列表失败：" + var24.getMessage());
        } finally {
            if (null != ctx) {
                try {
                    ctx.close();
                } catch (NamingException var23) {
                    throw new CryptOperatorException("ldap流关闭失败");
                }
            }
        }
        return var26;
    }
}
